// For grabbing "Next" Campaign Member 
public class CXGSnapshotController
{    
    public Id nextMemberId {get;set;}
    public String viewName {get;set;}
    public String Text {get;set;}  
    private CXG_Campaign_Accounts__c cm;
    public Integer CurrentHour {get;set;}
           
    public CXGSnapshotController(ApexPages.StandardController controller)
    {
		cm = (CXG_Campaign_Accounts__c)controller.getRecord();
		DateTime dt = DateTime.now(); // Returns the current Datetime based on a GMT calendar.
		CurrentHour = dt.hour(); // Returns the hour component of a Datetime in the local time zone of the context user
	}

	public void NextCall()
	{
		Integer hr = CurrentHour;
		System.debug('Hour=' + CurrentHour);
     
		System.debug('ViewName=' + viewName);
		System.debug('User=' + UserInfo.getUserId());
       
		// NOTE that currently the only User's of the CXG system are in Central time zone
		// so all these hour values listed below are assumed to be in CST.
		List<String> timezones = new List<String>();
		if (hr == 7){ // 7am
			timezones.add('EST');
		}
		else if (hr == 8){ // 8am
			timezones.add('EST');
			timezones.add('CST');
		}
		else if (hr == 9){ // 9am
			timezones.add('EST');
			timezones.add('CST');
			timezones.add('MST');
		}
		else if (hr >= 10 && hr <= 16){ // 10am - 4pm
			timezones.add('EST');
			timezones.add('CST');
			timezones.add('MST');
			timezones.add('PST');
		}
		else if (hr == 17){ // 5pm
			timezones.add('CST');
			timezones.add('MST');
			timezones.add('PST');
		}
		else if (hr == 18){ // 6pm
			timezones.add('MST');
			timezones.add('PST');
		}
		else if (hr == 19){ // 7pm
			timezones.add('PST');
		}
		
		// Don't allow the Agent to find any campaign members if it's outside the allowable calling hours
		if (timezones.size() > 0)
		{
			CXG_Campaign_Accounts__c randomCM = null;
			
			// First pick a "New" campaign member that they may have put into their own queue.	
			// This could happen if the users presses "Next" on a CM but doesn't disposition it.
			List<CXG_Campaign_Accounts__c> membs = [
				select Id, Contact_s_Timezone__c, OwnerId
				from CXG_Campaign_Accounts__c
				where Campaign_Paused__c = false
				and Contact_s_Timezone__c in :timezones
				and OwnerId = :UserInfo.getUserId() 
				and Status__c = 'New'
				and Disposition__c not in ('Left Message 2', 'Ring No Answer 3', 'Line Disconnected / Fax Line', 'D2')
				limit 1]; 
				
			System.debug('membsSize=' + membs.size());
			if (membs.size() > 0)
				randomCM = membs[0];
				
			// If we didn't find a CM that we own in the "New" status, apply the random logic to find another available member.
			if (randomCM == null)
			{
				// Query Campaign Members that are not in a final disposition state belonging to specific timezones
				membs = [
					select Id, Contact_s_Timezone__c, OwnerId
					from CXG_Campaign_Accounts__c
					where Campaign_Paused__c = false
					and Contact_s_Timezone__c in :timezones
					and (Owner.Name = :viewName or (OwnerId = :UserInfo.getUserId() and Status__c = 'In Progress - Contacted' and Call_Back_Scheduled__c = false))
					and Disposition__c not in ('Left Message 2', 'Ring No Answer 3', 'Line Disconnected / Fax Line', 'D2')
					and Status__c not in ('Closed', 'Completed')];
				
				System.debug('membsSize=' + membs.size());
				if (membs.size() > 0)
				{
					// Choose a random campaign member from all available.
					Integer randomInt = GetRandomInt(membs.size());
					System.debug('randomInt=' + randomInt);
					randomCM = membs[randomInt];				
				}
			}
			
			System.debug('randomCM=' + randomCM);	
			if (randomCM != null)
			{
				nextMemberId = randomCM.Id;
					
				// If it wasn't already owned by the current user, make it so.
				if (randomCM.OwnerId != UserInfo.getUserId())
				{
					randomCM.OwnerId = UserInfo.getUserId();				
					update randomCM;
				}
			}
		}
		else
		{
			// No campaign member available for display
			nextMemberId = null;
			PageReference pageref = new PageReference('/ui/support/servicedesk/ServiceDeskPage');
		}
	}
	
	// Returns a random integer between 0 and maxInt. The number will never equal maxInt though. 
	// Close enough to random for our purposes! ;)
	private Integer GetRandomInt(Integer maxInt)
	{
		return Math.abs(Math.mod(Crypto.getRandomInteger(), maxInt)); 
	}
}